#include "list.h"

void list::Insert(int _d){
	node* pNew = new node;
	pNew->setData(_d);
	pTail = pNew;
	
	node* pCur = pHead;
	node* pPre = pCur;

	if(pHead == NULL)
		pHead = pNew;
	else{
		while(pCur){
			pPre = pCur;
			pCur = pCur->getNext();				
		}
		pPre->setNext(pNew); //last node link
		pNew->setRear(pPre); //pNew link pre node
	}	

}

void list::Delete(int _d){
	node* pCur = pHead;
	node* pPre = pCur;
	node* temp = NULL;
	if(pHead == NULL){
		cout<<"pHead is NULL"<<endl;
		return;	
	}
	
	if(pHead->getData() == _d ) {
		temp = pHead;		
		pHead = pHead->getNext();
		delete temp;
		pHead->setRear(NULL);
		return;
	}
	else{//total node upper 2
		while(pCur){
			if(pPre->getData() == _d){
				temp = pPre;
				break;			
			}
			pPre = pCur;
			pCur = pCur->getNext();
		}
	}

	if(temp == NULL){
		cout<<"there is no target to delete !!"<<endl;
		return;	
	}

	if(temp == pHead){ // target is pHead
		pHead = pHead->getNext();
		pHead->setRear(NULL);
		delete temp;
	}
	else if(temp == pTail){ // target is tail;
		pTail->getRear()->setNext(NULL);
		delete temp;
	}
	else{ //target is middle
		temp->getRear()->setNext(temp->getNext() );
		temp->getNext()->setRear(temp->getRear() );
		delete temp;
	}

}


void list::print(){
	node* pCur = pHead;
	node* pPre = pCur;
	cout<<"=====PRINT Data====="<<endl;

	while(pCur){
		cout<<pCur->getData()<<" ";
		pPre = pCur;
		pCur = pCur->getNext();
		cout<<endl;
	}

}

void list::swap_data(int a, int b){
	node* pCur = pHead;
	node* pPre = pCur;
	node* target_a = NULL;
	node* target_b = NULL;
	node* temp = NULL;
	node* temp2 = NULL;

	if(pHead == NULL){
		cout<<"pHead is NULL"<<endl;
		return;
	}
	
	while(pCur){ //match data
		pPre = pCur;
		pCur = pCur->getNext();
		if(pPre->getData() == a){
			target_a = pPre;					
		}
		if(pPre->getData() == b){
			target_b = pPre;
		}	
	}
	


	if(target_a == NULL || target_b == NULL ) {	
		cout<<a<<" or "<<b<<" are not here "<<endl;
		return;	
	}

	if(target_a == pHead){
		if(target_b == target_a->getNext() ) { //targetnodes are injected
			if(target_b->getNext() == NULL) { //2 node injected
				pHead = target_b;
				pTail = target_a;
				target_b->setNext(target_a);
				target_a->setRear(target_b);
				target_a->setNext(NULL);
				target_b->setRear(NULL);
			}
			else{ // 3 upper node injected
				target_a->setNext(target_b->getNext() );
				target_a->setRear(target_b);
				target_b->setNext(target_a);
				target_b->setRear(NULL);
				pHead = target_b;			
			}
		}
		else if(target_b == pTail){
			pHead->setRear(pTail->getRear() );
			pTail->setNext(pHead->getNext() );
			pHead->setNext(NULL);
			pTail->setRear(NULL);
		}
		else{//target_b is middle
			temp = target_a->getNext();
			target_a->setNext(target_b->getNext() );
			target_b->getNext()->setRear(target_a);
			target_b->getRear()->setNext(target_a);
			target_a->setRear(target_b->getRear() );
			target_b->setRear(NULL);
			target_b->setNext(temp);
			temp->setRear(target_b);
			pHead = target_b;

		}	
	}

	else if(target_b == pTail){
		if(target_a == target_b->getRear() ){
			target_b->setRear(target_a->getRear() );
			target_a->getRear()->setNext(target_b );
			target_b->setNext(target_a);
			target_a->setRear(target_b);
			target_a->setNext(NULL);
			pTail = target_a;
		}
		else{
			temp = target_b->getRear();
			target_b->setNext(target_a->getNext() );
			target_a->getNext()->setRear(target_b);
			target_b->setRear(target_a->getRear() );
			target_a->getRear()->setNext(target_b);
			target_a->setRear(temp);
			temp->setNext(target_a);
			target_a->setNext(NULL);
			pTail = target_a;
		
		}
		
	}

	else{ //each are not tail,head
		if(target_a->getNext() != target_b){
			temp = target_a->getNext();
			temp2 = target_b->getRear();
			target_a->setNext(target_b->getNext() );
			temp2->setNext(target_a);
			target_b->setRear(target_a->getRear() );
			target_b->getRear()->setNext(target_b);
			target_a->setRear(temp2);		
			target_b->setNext(temp);
			temp->setRear(target_b);
		}
		else{
			target_a->setNext(target_b->getNext());
			target_b->getNext()->setRear(target_a);
			target_a->getRear()->setNext(target_b);
			target_b->setRear(target_a->getRear());
			target_a->setRear(target_b);
			target_b->setNext(target_a);	
		}
	}	

}

void list::sort(){
	node* pCur = pHead;
	node* pPre = pCur;

	while(pCur){
		if(pPre->getData() > pPre->getNext()->getData() ){
			swap_data(pPre->getData(),pPre->getNext()->getData() );
			pCur = pHead;
			pPre = pCur;
		}
		pPre = pCur;
		pCur = pCur->getNext();

	}


}
